package com.athuahua.security.config;

import com.athuahua.security.component.ARUDS;
import jakarta.annotation.Resource;
import org.springframework.boot.autoconfigure.security.reactive.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.authentication.UserDetailsRepositoryReactiveAuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.server.SecurityWebFilterChain;

/**
 * @Author: huahua
 * @Date: 2024/12/11 0011
 * @Time: 13:47
 * @Description:
 */
@Configuration
@EnableReactiveMethodSecurity //开启响应式基于方法级别的权限控制
public class AppSecurityConfiguration {

    @Resource
    private ARUDS aruds;

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        //1 定义哪些请求需要认证，哪些不需要
        http.authorizeExchange(authorize -> {
            //允许所有人都能访问
            //authorize.pathMatchers("/js/**").permitAll();

            //1.1 允许所有人都能访问静态资源 [PathRequest需要响应式包下的]
            authorize.matchers(PathRequest.toStaticResources().atCommonLocations())
                    .permitAll();

            //1.2 剩下的所有请求都需要认证
            authorize.anyExchange().authenticated();
        });
        //2 开启默认的表单登录
        http.formLogin();

        //3. 禁用安全控制
        http.csrf(csrfSpec -> {
            csrfSpec.disable();
        });

        //目前认证：用户名user 密码是默认生成的
        //期望的认证：去数据库查询用户名和密码

        //4. 配置 认证规则： 去数据库查询用户
        http.authenticationManager(new UserDetailsRepositoryReactiveAuthenticationManager(aruds));

        //构建安全配置
        return http.build();
    }


    @Primary
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
